package org.maxgroundstation.groundstation.comm.service;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

/**
 * Handles all TCP service communication.
 * @author Scott Davis
 * 
 * Copyright (C) 2010  Scott Davis
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
public class ServiceCommunicationTCP {
	
	// Default TCP port
	private static final int DEFAULT_PORT = 10001;
	
	// Data members
	private ServiceCommunication comm;
    private int port;
    private Socket socket;
    private ServiceReceiverTCP receiver;
    private ServiceSenderTCP sender;
    
    /**
     * Constructor
     * @param comm the service communication.
     */
    ServiceCommunicationTCP(ServiceCommunication comm) {
    	this.comm = comm;
    	port = DEFAULT_PORT;
    	socket = null;
    	receiver = new ServiceReceiverTCP(this);
    	sender = new ServiceSenderTCP(this);
    }
    
    /**
     * Gets the service communication.
     * @return service communication.
     */
    ServiceCommunication getServiceCommunication() {
    	return comm;
    }
    
    /**
     * Gets the current port number.
     * @return port number.
     */
    int getPort() {
        return port;
    }
    
    /**
     * Sets the port number.
     * @param port the new port number.
     */
    void setPort(int port) {
        this.port = port;
    }
    
    /**
     * Checks if connected to robot.
     * @return true if connected
     */
    boolean isConnected() {
        return (socket != null) && socket.isConnected() && !socket.isClosed();
    }
    
    /**
     * Connects to the TCP communication socket.
     * @throws IOException if error connecting to socket.
     */
    void connect() throws IOException {
    	if (socket != null) socket.close();
    	
    	// Connect TCP socket.
    	InetAddress address = InetAddress.getByName(comm.getIPAddress());
    	socket = new Socket(address, getPort());
    	
    	System.out.println("Connection TCP Service on " + address.toString() + " port: " + port);
    	
    	// Initialize receiver input data stream.
    	receiver.initializeInputDataStream();	
    	receiver.start();
    	
    	// Initialize sender output data stream.
    	sender.initializeOutputDataStream();
    }
    
    /**
     * Closes the TCP communication socket.
     * @throws IOException if error closing socket.
     */
    void disconnect() throws IOException {
    	if (isConnected()) {
    		System.out.println("Disconnecting TCP service socket");
    		socket.close();
    	}
        
    	// Close receiver input data stream.
        receiver.closeInputDataStream();
        receiver.setRun(false);
        
        // Close sender output data stream.
        sender.closeOutputDataStream();
    }
    
    /**
     * Gets the TCP socket.
     * @return socket.
     */
    Socket getSocket() {
    	return socket;
    }
    
    /**
     * Sends a service post with data to the robot.
     * @param serviceID the service ID string.
     * @param data the data bytes.
     * @throws Exception if error sending service post.
     */
    public void sendServicePost(String serviceID, byte[] data) throws Exception {
    	if (data == null) throw new IllegalArgumentException("data cannot be null");
    	sender.sendServicePost(serviceID, data);
    }
}